package com.wondream.myframework.app.common.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonGenerator;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Map;

public class HttpJsonUtil {

    private static final ObjectMapper objectMapper = new ObjectMapper();
    static {
        objectMapper.getFactory().configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);
    }

    public static String getQueryUrl(String url, Map<String, String> queryParams){
        return String.format("%s?%s", url, toQueryString(queryParams));
    }

    public static String toQueryString(Map<String, String> params) {
        if (params == null || params.isEmpty()) {
            return "";
        }

        StringBuilder queryString = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (queryString.length() > 0) {
                queryString.append('&');
            }
            queryString.append(entry.getKey()).append('=').append(entry.getValue());
        }
        return queryString.toString();
    }

    public static <T> T get(String url, Class<T> responseType) throws Exception {
        LogUtils.op("发起get请求").kv("url", url).info();
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String result = EntityUtils.toString(entity);
                LogUtils.op("解析get请求结果").kv("result", JSON.toJSONString(JSON.parse(result))).info();
                return objectMapper.readValue(result, responseType);
            } else {
                throw new RuntimeException("Response is empty");
            }
        }
    }

    // This method can be used to post JSON data and parse the response as JSON
    public static <T> T post(String url, Object request, Class<T> responseType) throws Exception {

        LogUtils.op("发起post请求").kv("url", url).kv("params", JSON.toJSONString(request)).info();

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        StringEntity input = new StringEntity(objectMapper.writeValueAsString(request));
        input.setContentType("application/json");
        httpPost.setEntity(input);

        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String result = EntityUtils.toString(entity);
                LogUtils.op("解析post请求结果").kv("result", JSON.toJSONString(JSON.parse(result))).info();
                return objectMapper.readValue(result, responseType);
            } else {
                throw new RuntimeException("Response is empty");
            }
        }
    }

    // This method can be used to post JSON data and parse the response as JSON
    public static <T> T post(String url, Object request, Map<String, String> headers, Class<T> responseType) throws Exception {

        LogUtils.op("发起post请求").kv("url", url).kv("params", JSON.toJSONString(request)).info();

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        StringEntity input = new StringEntity(objectMapper.writeValueAsString(request));
        input.setContentType("application/json");
        httpPost.setEntity(input);
        headers.entrySet().forEach(entry->{
            httpPost.setHeader(entry.getKey(), entry.getValue());
        });
        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String result = EntityUtils.toString(entity);
                LogUtils.op("解析post请求结果").kv("result", JSON.toJSONString(JSON.parse(result))).info();
                return objectMapper.readValue(result, responseType);
            } else {
                throw new RuntimeException("Response is empty");
            }
        }
    }
}